package com.wn.icloud.provider.uac.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.wn.icloud.common.msg.ObjectRestCode;
import com.wn.icloud.common.msg.ObjectRestResponse;
import com.wn.icloud.common.util.IpUtils;
import com.wn.icloud.common.utils.sms.SendSmsUtil;
import com.wn.icloud.provider.uac.mapper.UserMapper;
import com.wn.icloud.provider.uac.remote.constant.UserRedisKeyConstant;
import com.wn.icloud.provider.uac.service.SendSmsService;
import com.wn.icloud.provider.uac.vo.SendSmsReqVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service("sendSmsServiceImpl")
public class SendSmsServiceImpl implements SendSmsService {


    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Value("${sms.time}")
    private Long smsTime;


    @Value("${sms.phone.limit}")
    private Integer phoneLimitNumber;

    @Value("${sms.phone.time}")
    private Long phoneLimitTime;

    //todo 目前ip限频过大，后续获取到真实ip后修改为较小值
    @Value("${sms.ip.limit}")
    private Integer ipLimitNumber;

    @Value("${sms.ip.time}")
    private Long ipLimitTime;

    /**
     * 发送短信验证码
     *
     * @param sendSmsReqVO
     */
    @Override
    public ObjectRestResponse sendSms(SendSmsReqVO sendSmsReqVO) {
        //todo 上线后解开注释,与前端协调加密方式
//        String encrypted = SendSmsUtil.encrypted(sendSmsReqVO.getPhoneNumber());
//        if (!encrypted.equals(sendSmsReqVO.getSsCode())){
//            return ObjectRestResponse.failure(ObjectRestCode.FAILURE, null);
//        }
        String ip = IpUtils.getRemoteIp();
        System.out.println("真实ip地址---" + ip);
        int i = userMapper.queryExsitPhone(sendSmsReqVO.getPhoneNumber());
        String redisKey;
        String redisPhoneLimit;
        switch (sendSmsReqVO.getType()) {
            case "1"://登录
                redisKey = UserRedisKeyConstant.LOGIN;
                redisPhoneLimit = UserRedisKeyConstant.LOGIN_LIMIT;
                if (i == 0){
                    return ObjectRestResponse.failure(ObjectRestCode.USER_NOT_EXIST);
                }
                break;
            case "2"://注册
                redisKey = UserRedisKeyConstant.REGISTER;
                redisPhoneLimit = UserRedisKeyConstant.REGISTER_LIMIT;
                if (i == 1){
                    return ObjectRestResponse.failure(ObjectRestCode.USER_HAS_EXISTED);
                }
                break;
            case "3"://忘记密码
                redisKey = UserRedisKeyConstant.RESET_PASSWORD;
                redisPhoneLimit = UserRedisKeyConstant.RESET_PASSWORD_LIMIT;
                if (i == 0){
                    return ObjectRestResponse.failure(ObjectRestCode.USER_NOT_EXIST_GO_REGISTER);
                }
                break;
            default:
                return ObjectRestResponse.failure(ObjectRestCode.FAILURE, null);
        }
        redisKey = redisKey + sendSmsReqVO.getPhoneNumber();
        redisPhoneLimit = redisPhoneLimit + sendSmsReqVO.getPhoneNumber();
        Object redisPhoneLimitValue = redisTemplate.opsForValue().get(redisPhoneLimit);
        String ipRedisLimitKey = UserRedisKeyConstant.IP_LIMIT + ip;
        Object ipRedisLimitValue = redisTemplate.opsForValue().get(ipRedisLimitKey);
        if (!smsLimit(redisPhoneLimit, redisPhoneLimitValue, phoneLimitNumber, phoneLimitTime) || !smsLimit(ipRedisLimitKey, ipRedisLimitValue, ipLimitNumber, ipLimitTime)){
            return ObjectRestResponse.failure(ObjectRestCode.FAILURE_LIMIT, null);// 请求频繁 请稍候再试
        }
        int randomNumber = sixCode();
        // 发送短信
        String smsResultData = SendSmsUtil.sendSms(sendSmsReqVO.getPhoneNumber(), randomNumber);
        JSONObject smsResultObj = JSONObject.parseObject(smsResultData);
        String message = smsResultObj.get(SendSmsUtil.Message).toString();
        if (StringUtils.isEmpty(smsResultData) || StringUtils.isEmpty(message) || !SendSmsUtil.ok.equals(message)){
            return ObjectRestResponse.failure(ObjectRestCode.FAILURE, smsResultData);// 短信验证码发送失败
        }
        redisTemplate.opsForValue().increment(redisPhoneLimit,1);
        redisTemplate.opsForValue().increment(ipRedisLimitKey,1);
        redisTemplate.opsForValue().set(redisKey, randomNumber);
        redisTemplate.expire(redisKey,smsTime , TimeUnit.MILLISECONDS);
        return ObjectRestResponse.success(randomNumber);// 发送成功 return code
    }

    /**
     * 生成六位随机数
     */
    public static int sixCode(){
        Random random = new Random();
        int randInt = 0;
        do {
            randInt = random.nextInt(1000000);
        } while (randInt < 100000);
        System.out.println(randInt);
        return randInt;
    }

    public boolean smsLimit(String redisKey, Object redisValue, int limitNumber, Long time){
        if (StringUtils.isEmpty(redisValue)){
            redisTemplate.opsForValue().set(redisKey, 0);
            redisTemplate.expire(redisKey,time , TimeUnit.MILLISECONDS);

        }else {
            if (redisValue.toString().equals(String.valueOf(limitNumber))){
                return false;//请求频繁，请稍候再试
            }
        }
        return true;
    }


}
